package cn.zftt.quartz.dao.impl;

import cn.zftt.quartz.dao.JobDao;
import cn.zftt.quartz.model.Job;
import cn.zftt.quartz.model.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * @author zhangfeng
 */
@Component
public class JobDaoImpl implements JobDao {

    private final JdbcTemplate jdbcTemplate;

    private final String queryJobsSQL =
            "SELECT\n" +
                    "\tJOB.JOB_NAME,\n" +
                    "\tJOB.JOB_GROUP,\n" +
                    "\tJOB.DESCRIPTION,\n" +
                    "\tJOB.JOB_CLASS_NAME,\n" +
                    "\tTGR.TRIGGER_STATE,\n" +
                    "\tTGR.PREV_FIRE_TIME,\n" +
                    "\tTGR.NEXT_FIRE_TIME,\n" +
                    "\tCRT.CRON_EXPRESSION \n" +
                    "FROM\n" +
                    "\tQRTZ_JOB_DETAILS JOB\n" +
                    "\tJOIN QRTZ_TRIGGERS TGR ON TGR.JOB_NAME = JOB.JOB_NAME\n" +
                    "\tJOIN QRTZ_CRON_TRIGGERS CRT ON CRT.TRIGGER_NAME = TGR.TRIGGER_NAME \n" +
                    "WHERE\n" +
                    "\tJOB.SCHED_NAME = ? ";

    private final String queryLike = " AND JOB.JOB_NAME LIKE CONCAT(CONCAT('%', ?), '%')";

    @Value("${spring.quartz.properties.org.quartz.scheduler.instanceName}")
    private String schedName;


    @Override
    public Page<Job> queryAllJobs(Page page) {
        if (page != null) {
            Integer total = jdbcTemplate.queryForObject("SELECT COUNT(1) FROM (" + queryJobsSQL + ")", Integer.class, schedName);
            page.setTotal(total);

            List<Job> jobs = jdbcTemplate.query(queryJobsSQL + " LIMIT " + (page.getCur() - 1) * page.getSize() + "," + page.getSize(), new JobMapper(), schedName);
            page.setRows(jobs);

            return page;
        }
        Page<Job> t = new Page<>();
        t.setTotal(0);
        t.setRows(Collections.emptyList());
        return t;
    }

    @Override
    public Page<Job> queryJobs(Job job) {
        if (job != null) {
            Integer total = jdbcTemplate.queryForObject("SELECT COUNT(1) FROM (" + queryJobsSQL + queryLike + ")", Integer.class, schedName, job.getName().trim());
            job.setTotal(total);

            List<Job> jobs = jdbcTemplate.query(queryJobsSQL + queryLike + " LIMIT " + (job.getCur() - 1) * job.getSize() + "," + job.getSize(), new JobMapper(), schedName, job.getName().trim());
            job.setRows(jobs);

            return job;
        }
        Page<Job> t = new Page<>();
        t.setTotal(0);
        t.setRows(Collections.emptyList());
        return t;
    }

    private class JobMapper implements RowMapper<Job> {

        @Override
        public Job mapRow(ResultSet resultSet, int i) throws SQLException {
            Job job = new Job();
            job.setName(resultSet.getString("JOB_NAME"));
            job.setGroup(resultSet.getString("JOB_GROUP"));
            job.setDescription(resultSet.getString("DESCRIPTION"));
            job.setClassName(resultSet.getString("JOB_CLASS_NAME"));
            job.setState(resultSet.getString("TRIGGER_STATE"));
            job.setCronExpression(resultSet.getString("CRON_EXPRESSION"));
            job.setNextTime(new Date(resultSet.getLong("NEXT_FIRE_TIME")));
            job.setPrevTime(new Date(resultSet.getLong("PREV_FIRE_TIME")));
            return job;
        }

    }


    @Autowired
    public JobDaoImpl(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }


}
